home *** CD-ROM | disk | FTP | other *** search
/ Workbench Add-On / Workbench Add-On - Volume 1.iso / BBS-Archive / Comm / AmiTCP30b2.lha / src / netlib / _chkufb.c < prev    next >
C/C++ Source or Header  |  1994-04-12  |  3KB  |  157 lines

  1. RCS_ID_C="$Id: _chkufb.c,v 1.5 1994/04/12 20:49:04 jraja Exp $";
  2. /*
  3.  * _chkufb.c --- return struct ufb * from a file handle
  4.  *
  5.  * Author: jraja <Jarno.Rajahalme@hut.fi>
  6.  *
  7.  * This file is part of the AmiTCP/IP Network Support Library.
  8.  *
  9.  * Copyright © 1994 AmiTCP/IP Group, <amitcp-group@hut.fi>
  10.  *                  Helsinki University of Technology, Finland.
  11.  *                  All rights reserved.
  12.  *
  13.  * Created      : Thu Mar 17 21:52:13 1994 jraja
  14.  * Last modified: Wed Mar 30 10:30:24 1994 jraja
  15.  *
  16.  */
  17.  
  18. #include <ios1.h>
  19. #include <stdlib.h>
  20. #include <errno.h>
  21. #include <bsdsocket.h>
  22. #include <sys/cdefs.h>
  23. #include <amitcp/socketbasetags.h>
  24. #include <syslog.h>
  25.  
  26. extern unsigned long __fmask;
  27. extern int (*__closefunc)(int);
  28.  
  29. long ASM fdCallback(REG(d0) int fd, REG(d1) int action);
  30.  
  31. /*
  32.  * The initializator priority is just above the standard I/O, so that this
  33.  * will be called after the standard I/O is initialized
  34.  */
  35. long __stdargs
  36. _STI_510_install_AmiTCP_callback(void)
  37. {
  38.   if (SocketBaseTags(SBTM_SETVAL(SBTC_FDCALLBACK), &fdCallback, TAG_END)) {
  39.     syslog(LOG_ERR, "Cannot install fdCallback!");
  40. #if __VERSION__ > 6 || __REVISION__ > 3
  41.     return 1;
  42. #else
  43.     exit(20);
  44. #endif
  45.   }
  46.  
  47.   /*
  48.    * Set up __closefunc (which is used at stdio cleanup)
  49.    */
  50.   __closefunc = __close;
  51.  
  52.   /*
  53.    * Set default file mask to UNIX style
  54.    */
  55.   __fmask = 0644; 
  56.  
  57.   return 0;
  58. }
  59.  
  60. long ASM SAVEDS
  61. fdCallback(REG(d0) int fd, REG(d1) int action)
  62. {
  63.   struct UFB *ufb;
  64.   int fd2;
  65.  
  66. #ifdef DEBUG
  67.   syslog(LOG_INFO, "fdCallback(fd: %d, action: %d)", fd, action);
  68. #endif
  69.  
  70.   switch (action) {
  71.   case FDCB_FREE:
  72.     ufb = __chkufb(fd);
  73.     if (ufb == NULL)
  74.       return EBADF;
  75.  
  76.     if (!(ufb->ufbflg & UFB_SOCK) && ufb->ufbflg != 0) {
  77. #ifdef DEBUG
  78.       syslog(LOG_ERR, "fdCallback: fd (%d) is not a socket!", fd);
  79. #endif
  80.       return ENOTSOCK;
  81.     }
  82.  
  83.     ufb->ufbflg = 0;
  84.     return 0;
  85.  
  86.   case FDCB_ALLOC:
  87.     do {
  88.       ufb = __allocufb(&fd2);
  89.       if (ufb == NULL)
  90.     return ENOMEM;
  91. #ifdef DEBUG
  92.       if (fd2 > fd) {
  93.     syslog(LOG_ERR, "fdCallback: fd2(%d) > fd(%d)!", fd2, fd);
  94.     return EINVAL;
  95.       }
  96. #endif
  97.       ufb->ufbflg = UFB_SOCK | UFB_WA | UFB_RA; /* read/write socket */
  98.       ufb->ufbfh = NULL; /* no file handle */
  99.       ufb->ufbfn = NULL; /* no name */
  100.     } while (fd2 < fd);
  101.     return 0;
  102.  
  103.   case FDCB_CHECK:
  104.     ufb = __chkufb(fd);
  105.     if (ufb != NULL && ufb->ufbflg != 0) 
  106.       return EBADF;
  107.     
  108.     return 0;
  109.  
  110.   default:
  111. #ifdef DEBUG
  112.     syslog(LOG_ERR, "fdCallback: invalid action.");
  113. #endif
  114.     return EINVAL;
  115.   }
  116. }
  117.  
  118.  
  119. struct UFB *
  120. __chkufb(int fd)
  121. {
  122.   struct UFB *ufb;
  123.  
  124.   /* a single element cache */
  125.   static struct UFB *last_ufb = NULL;
  126.   static int         last_fd = -1;
  127.  
  128.   _OSERR = 0;
  129.  
  130.   if ((unsigned int)fd >= __nufbs) { /* unsigned cast checks for (fd < 0) */
  131.     errno = EBADF;
  132.     return NULL;
  133.   }
  134.  
  135.   /*
  136.    * Check the cache first
  137.    */
  138.   if (fd == last_fd)
  139.     return last_ufb;
  140.  
  141.   last_fd = fd; /* update cache */
  142.   ufb = __ufbs;
  143.   while (fd > 0 && ufb != NULL) {
  144.     fd--;
  145.     ufb = ufb->ufbnxt;
  146.   }
  147.   last_ufb = ufb; /* update cache */
  148.   
  149.   if (ufb == NULL) {
  150.     last_fd = -1; /* invalidate cache */
  151.     errno = EIO;
  152.     return NULL;
  153.   }
  154.   else
  155.     return ufb;
  156. }
  157.